package tbc

import (
	"fmt"
	"github.com/gocolly/colly"
	"github.com/gogf/gf/v2/frame/g"
	"github.com/gogf/gf/v2/os/gctx"
	"github.com/gogf/gf/v2/os/gtime"
	"github.com/gogf/gf/v2/text/gregex"
	"github.com/gogf/gf/v2/util/gconv"
	"time"
	"uni-crawl-frame/core"
	"uni-crawl-frame/db/mysql/model/entity"
	"uni-crawl-frame/service/crawl/replayservice"
	"uni-crawl-frame/utils/timeutil"
)

type TbcCrawl struct {
	*core.AbstractCrawlReplayUrl
}

// CreateProgram eg: https://www.tbc.net.tw/Epg/Channel?channelId=068
func (receiver *TbcCrawl) CreateProgram(replayConfig *entity.CmsCrawlReplayConfig, manifestTask *entity.CmsCrawlReplayManifestTask) {
	log := g.Log().Line()
	programTitle := ""

	now := time.Now()
	todayStr := now.Format(timeutil.YYYY_MM_DD)

	coll := colly.NewCollector()

	coll.OnXML("//*[@class='ch_info']", func(element *colly.XMLElement) {
		programTitle = element.Attr("title")
		log.Infof(gctx.GetInitCtx(),
			"tbc电视台名称 = %s", programTitle)
	})

	coll.OnXML("//*[@class='list_program2'][1]/li", func(element *colly.XMLElement) {

		title := element.Attr("title")
		dateStr := element.Attr("date")
		timeDurationStr := element.Attr("time") // eg: 19:45~21:45
		_ = element.Attr("desc")

		date, _ := time.Parse(timeutil.YYYY_MM_DD_SLASH, dateStr)
		stdDateStr := date.Format(timeutil.YYYY_MM_DD) // 标准格式
		if todayStr != stdDateStr {
			return
		}

		times, _ := gregex.MatchString("(\\d{2}):(\\d{2})~(\\d{2}):(\\d{2})", timeDurationStr)
		lHourStr := times[1]
		lMinuteStr := times[2]
		rHourStr := times[3]
		rMinuteStr := times[4]
		log.Infof(gctx.GetInitCtx(),
			"节目 = %s. from %s:%s to %s:%s", title, lHourStr, lMinuteStr, rHourStr, rMinuteStr)

		startTime, _ := time.Parse(timeutil.YYYY_MM_DD_HH_MM_SS, fmt.Sprintf("%s %s:%s:00", todayStr, lHourStr, lMinuteStr))
		minutes := 0
		for {
			// 跨天的方式不方便计算需要录多久，因此用时间相加一分钟一分钟的去探测
			tmpTime := startTime.Add(time.Minute * time.Duration(minutes))
			rHour := gconv.Int(rHourStr)
			rMinute := gconv.Int(rMinuteStr)
			if tmpTime.Hour() == rHour && tmpTime.Minute() == rMinute {
				break
			}
			minutes += 1
		}

		programTask := new(entity.CmsCrawlReplayProgramTask)
		programTask.ManifestId = manifestTask.Id
		programTask.ConfigId = replayConfig.Id
		programTask.ProgramName = title
		programTask.CrawlStatus = replayservice.ProgramTaskInit

		programStartTime, _ := time.Parse(timeutil.YYYY_MM_DD_HH_MM_SS, fmt.Sprintf("%s %s:%s:00", todayStr, lHourStr, lMinuteStr))
		programTask.ProgramStartTime = gtime.NewFromTime(programStartTime)
		programTask.ProgramNo = programTask.ProgramStartTime.TimestampMilliStr()
		programTask.HostIp = replayConfig.Host
		sec := minutes * 60
		programTask.ProgramEndTime = programTask.ProgramStartTime.Add(gtime.S * time.Duration(sec))
		programTask.CreateTime = gtime.Now()

		replayservice.CheckAndSave(programTask)
	})

	_ = coll.Visit(replayConfig.SeedUrl)

}
